package drds.plus.executor.row_values;

import drds.plus.executor.cursor.cursor_metadata.CursorMetaData;
import drds.plus.sql_process.abstract_syntax_tree.configuration.ColumnMetaData;
import drds.plus.sql_process.type.Type;

import java.math.BigDecimal;
import java.sql.Date;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.List;

public abstract class AbstractRowValues implements RowValues {

    private final CursorMetaData cursorMetaData;

    public AbstractRowValues(CursorMetaData cursorMetaData) {
        super();
        this.cursorMetaData = cursorMetaData;
    }

    public CursorMetaData getParentCursorMetaData() {
        return cursorMetaData;
    }

    public Integer getInteger(int index) {
        ColumnMetaData columnMetaData = this.cursorMetaData.getColumnMetaData(index);
        return Type.IntegerType.convert(columnMetaData.getType().getResultGetter().get(this, index));
    }

    public void setInteger(int index, Integer value) {
        setObject(index, value);
    }

    public Long getLong(int index) {
        ColumnMetaData columnMetaData = cursorMetaData.getColumnMetaData(index);
        return Type.LongType.convert(columnMetaData.getType().getResultGetter().get(this, index));
    }

    public void setLong(int index, Long value) {
        setObject(index, value);
    }

    public String getString(int index) {
        ColumnMetaData columnMetaData = cursorMetaData.getColumnMetaData(index);
        return Type.StringType.convert(columnMetaData.getType().getResultGetter().get(this, index));
    }

    public void setString(int index, String str) {
        setObject(index, str);
    }

    public Boolean getBoolean(int index) {
        ColumnMetaData columnMetaData = cursorMetaData.getColumnMetaData(index);
        return Type.BooleanType.convert(columnMetaData.getType().getResultGetter().get(this, index));
    }

    public void setBoolean(int index, Boolean bool) {
        setObject(index, bool);
    }

    public Short getShort(int index) {
        ColumnMetaData columnMetaData = cursorMetaData.getColumnMetaData(index);
        return Type.ShortType.convert(columnMetaData.getType().getResultGetter().get(this, index));
    }

    public void setShort(int index, Short shortval) {
        setObject(index, shortval);
    }

    public Float getFloat(int index) {
        ColumnMetaData columnMetaData = cursorMetaData.getColumnMetaData(index);
        return Type.FloatType.convert(columnMetaData.getType().getResultGetter().get(this, index));
    }

    public void setFloat(int index, Float fl) {
        setObject(index, fl);
    }

    public Double getDouble(int index) {
        ColumnMetaData columnMetaData = cursorMetaData.getColumnMetaData(index);
        return Type.DoubleType.convert(columnMetaData.getType().getResultGetter().get(this, index));
    }

    public void setDouble(int index, Double doub) {
        setObject(index, doub);
    }


    public Date getDate(int index) {
        ColumnMetaData columnMetaData = cursorMetaData.getColumnMetaData(index);
        return Type.DateType.convert(columnMetaData.getType().getResultGetter().get(this, index));
    }

    public void setDate(int index, Date date) {
        setObject(index, date);
    }

    public Timestamp getTimestamp(int index) {
        ColumnMetaData columnMetaData = cursorMetaData.getColumnMetaData(index);
        return Type.TimestampType.convert(columnMetaData.getType().getResultGetter().get(this, index));
    }

    public void setTimestamp(int index, Timestamp timestamp) {
        setObject(index, timestamp);
    }

    public Time getTime(int index) {
        ColumnMetaData columnMetaData = cursorMetaData.getColumnMetaData(index);
        return Type.TimeType.convert(columnMetaData.getType().getResultGetter().get(this, index));
    }

    public void setTime(int index, Time time) {
        setObject(index, time);
    }

    public BigDecimal getBigDecimal(int index) {
        ColumnMetaData columnMetaData = cursorMetaData.getColumnMetaData(index);
        return Type.BigDecimalType.convert(columnMetaData.getType().getResultGetter().get(this, index));
    }

    public void setBigDecimal(int index, BigDecimal bigDecimal) {
        setObject(index, bigDecimal);
    }


    public List<Object> getValueList() {
        throw new UnsupportedOperationException();
    }

    public String toString() {
        StringBuilder sb = new StringBuilder();
        List<Object> values = this.getValueList();
        for (ColumnMetaData columnMetaData : this.getParentCursorMetaData().getColumnMetaDataList()) {
            int index = this.getParentCursorMetaData().getIndex(columnMetaData.getTableName(), columnMetaData.getColumnName(), columnMetaData.getAlias());
            sb.append(columnMetaData.getColumnName() + ":" + values.get(index) + " ");
        }
        return sb.toString();
    }

}
